// 工具一:Partial

// 需求：定义一个相对完整的表达客户完整信息的数据接口
interface Iperson {
	id:string,
	phone:number,
	carId:string
}
let per:Iperson = {
	id:'xxxx',
	phone:666,
	carId:'川A5480'
}

// 领奖数据包 使用Partial将Iperson接口内部字段变成可选
let info:Partial<Iperson> = {
	phone:123123123
}

//工具二：Required  约束某个接口中所有属性变为必填

interface Iperson1 {
	id?:string,
	phone?:number,
	carId?:string
}
//登记用户完整信息
let per1:Required<Iperson1> = {
	id:'xxxx',
	phone:111,
	carId:'川B5480'
}
let info1:Iperson1 = {
	carId:'川B5480'
}

//工具三：Readonly
//将某个接口中的字段设为只读
let p3:Readonly<Iperson1> = {
	id:'111',
	phone:112233
}
// p3.id = '12313'//只读属性无法修改

//工具四：Pick 从某个接口中筛选出指定的属性

interface Iperson2 {
	id:string,
	phone:number,
	carId:string
}
//完整信息
let p2:Iperson2 = {
	id:'xxx',
	phone:123,
	carId:'B5480'
}
//通过识别车牌自动登录洗车
let info2:Pick<Iperson2,'carId'|'phone'> = {
	carId:'B5480',
	phone:123
}
//工具五：Record<key的类型，值的类型>  约束对象的键值对类型

// 方法一:不使用Record
// interface DetailType {
// 	title:string,
// 	decs:string
// }
// interface DataType {
// 	about:DetailType,
// 	product:DetailType
// }
// let pageData:DataType = {
// 	'about':{title:'xxx',decs:'skdlvcj'},
// 	'product':{title:'eee',decs:'aaaa'},
// }
//方法二：使用Record
interface DetailType {//约束键值
	title:string,
	decs:string
}
type PageKey = 'about'|'product'//约束键名
let pageData:Record<PageKey,DetailType> = {
	'about':{title:'xxx',decs:'skdlvcj'},
	'product':{title:'eee',decs:'aaaa'},
}

//工具六：Exclude  从一个联合类型中排除指定的类型

type Userinfo = 'name'|'age'|'sc'
let key:Exclude<Userinfo,'age'|'name'> = 'sc'

type Gender = 'boy'|'girl'|'other'
interface UserTypeEn {
	id?:string,
	age?:number,
	gender:Gender
}
interface UserTypeCn {
	id?:string,
	age?:number,
	gender:Exclude<Gender,'other'>
}
//国外用户
let u1:UserTypeEn = {
	gender:'other'
}
//国内用户
let u2:UserTypeCn = {
	gender:'boy'
}

// 工具七:Omit  从一个接口中排除指定的属性

//Pick反向操作
interface Iperson7 {
	id:string,
	phone:number,
	carId:string
}
//登记完整信息
let p7:Iperson7 = {
	id:'xxx',
	phone:123,
	carId:'B5480'
}
// 洗车的时候只需要车牌、身份证
let info7:Omit<Iperson7,'phone'> = {
	id:'123',
	carId:'川A666'
}

// 工具八:ReturnType
// 返回某个数据的类型

let sum8 = (a:number,b:number):number=>{
	return a + b
}
console.log(sum8(3,6));

let multi:ReturnType<typeof sum8> = 132

function returnObj(){
	//其他操作
	return {
		'_id':'0x1707',
		'name':'xxx',
		skills:['闪电五连鞭','以雷霆击碎黑暗',111]
	}
}

let o1:ReturnType<typeof returnObj> = {
	_id:'123',
	name:'xxxx',
	skills:['666'] 
}

// type与interface区别
// interface可以重复定义,type不能重复定义
// 使用建议
// 对象约束使用interface
// 普通类型,联合类型建议使用type
interface Animal9{
	name:string
}
interface Animal9{
	color:string
}
let cat9:Animal9 = {
	name:'cat',
	color:'blue'
}

// 类型断言
interface GoodType10{
	name:string,
	price:number,
	desc:string
}
//给商品设置默认值
let g:GoodType10 = {
	name:'',
	price:0,
	desc:''
}
let g1:GoodType10 = {} as GoodType10
